﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace Antlers
{
	internal class KeywordChecklist : CheckedListBox
	{
		private IEnumerable<Thumbnail> m_selectedThumbnails;
		private List<Thumbnail> m_loadingThumbnailsList;
		private SortedList<string, object> m_pendingKeywordsList;
		private object m_updateLock = new object();

		private static NewKeyword NEW_KEYWORD = new NewKeyword();

		internal KeywordChecklist()
		{
			this.
			ItemCheck += new ItemCheckEventHandler(Handler_ItemCheck);
		}

		internal void UpdateList(IEnumerable<Thumbnail> thumbnails)
		{
			m_selectedThumbnails = new List<Thumbnail>(thumbnails);
			m_loadingThumbnailsList = new List<Thumbnail>(m_selectedThumbnails);
			m_pendingKeywordsList = new SortedList<string, object>();
			Items.Clear();
			Items.Add(new Loading());
		
			IEnumerable<Thumbnail> sourceList = m_selectedThumbnails;

			foreach (Thumbnail thumbnail in sourceList)
			{
				ThumbnailIO.PrepareResource(thumbnail, ThumbnailIO.IOType.KeywordRead, KeywordsPreparedCallback);
			}
		}

		private void KeywordsPreparedCallback(Thumbnail thumbnail, ThumbnailIO.IOType type)
		{
			if (InvokeRequired)
			{
				Invoke(new ThumbnailIO.ThumbnailReadyCallback(KeywordsPreparedCallback), new object[] { thumbnail, type });
			}
			else
			{
				if (m_loadingThumbnailsList.Contains(thumbnail))
				{
					foreach (String keyword in thumbnail.Keywords)
					{
						if (!m_pendingKeywordsList.ContainsKey(keyword))
						{
							m_pendingKeywordsList.Add(keyword, null);
						}
					}

					m_loadingThumbnailsList.Remove(thumbnail);
				}

				if (m_loadingThumbnailsList.Count == 0)
				{
					Items.Clear();

					foreach (String keyword in m_pendingKeywordsList.Keys)
					{
						Items.Add(keyword, CheckState.Checked);
					}

					Items.Add(NEW_KEYWORD, false);
				}
			}
		}

		private void Handler_ItemCheck(object sender, ItemCheckEventArgs args)
		{
			if (Items[args.Index].Equals(NEW_KEYWORD) && args.NewValue.Equals(CheckState.Checked))
			{

				NewKeywordDialog dialog = new NewKeywordDialog();
				if (dialog.ShowDialog(this) == DialogResult.OK)
				{
					foreach (Thumbnail thumbnail in m_selectedThumbnails)
					{
						thumbnail.AddKeyword(dialog.InputValue);
					}

					UpdateList(m_selectedThumbnails);
				}

			}
			else if (args.NewValue.Equals(CheckState.Unchecked))
			{
				foreach (Thumbnail thumbnail in m_selectedThumbnails)
				{
					thumbnail.RemoveKeyword((String)Items[args.Index]);
				}

				UpdateList(m_selectedThumbnails);
			}
		}

		private class NewKeyword
		{
			public override string ToString()
			{
				return "New Keyword...";
			}
		}

		private class Loading
		{
			public override string ToString()
			{
				return "Loading...";
			}
		}
	}
}
